package com.iceframework.core.utils;

import java.io.File;
import java.io.IOException;

import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.CompilerConfiguration;

import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import groovy.lang.GroovyShell;

/**
 * GroovyUtils
 * 
 * @author Palo
 *
 */
public class GroovyUtils {

	private static GroovyClassLoader groovyClassLoader = null;

	private static void initGroovyClassLoader() {
		CompilerConfiguration config = new CompilerConfiguration();
		config.setSourceEncoding("UTF-8");
		// 设置该GroovyClassLoader的父ClassLoader为当前线程的加载器(默认)
		groovyClassLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);
	}

	/**
	 * 执行Groovy脚本
	 * 
	 * @param script 脚本
	 * @throws CompilationFailedException
	 * @throws IOException
	 */
	public static void execGroovyShell(String script) throws CompilationFailedException, IOException {
		GroovyShell groovyShell = new GroovyShell();
		groovyShell.evaluate(script);
	}

	/**
	 * 执行groovy文件
	 * 
	 * @param filePath 脚本文件路径
	 * @return
	 * @throws CompilationFailedException
	 * @throws IOException
	 */
	public static Object execGroovyShellFile(String filePath) throws CompilationFailedException, IOException {
		GroovyShell groovyShell = new GroovyShell();
		return groovyShell.evaluate(new File(filePath));
	}

	/**
	 * 获取GroovyObject对象
	 * 
	 * @param filePath
	 * @return
	 */
	public static GroovyObject getGroovyObject(String filePath) {
		File groovyFile = new File(filePath);
		if (!groovyFile.exists()) {
			throw new RuntimeException("脚本不存在");
		}
		initGroovyClassLoader();
		try {
			// 获得TestGroovy加载后的class
			Class<?> groovyClass = groovyClassLoader.parseClass(groovyFile);
			// 获得TestGroovy的实例
			return (GroovyObject) groovyClass.newInstance();
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		}
	}

	/**
	 * 执行方法带返回值
	 * 
	 * @param <T>
	 * @param groovyObject groovyObject对象(获取 GroovyUtils getGroovyObject)
	 * @param method方法名
	 * @param params       参数
	 * @param clazz        类
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T execMethod(GroovyObject groovyObject, String method, Object[] params, Class<T> clazz) {
		try {
			// 反射调用printArgs方法得到返回值
			Object methodResult = groovyObject.invokeMethod(method, params);
			if (methodResult != null) {
				return (T) methodResult;
			}
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		}
		return null;
	}

	/**
	 * 执行方法
	 * 
	 * @param <T>
	 * @param groovyObject groovyObject对象(获取 GroovyUtils getGroovyObject)
	 * @param method       方法名
	 * @param clazz        类
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T execMethod(GroovyObject groovyObject, String method, Class<T> clazz) {
		try {
			// 反射调用printArgs方法得到返回值
			Object methodResult = groovyObject.invokeMethod(method, null);
			if (methodResult != null) {
				return (T) methodResult;
			}
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		}
		return null;
	}

	/**
	 * 执行方法
	 * 
	 * @param <T>
	 * @param filePath Groovy文件地址
	 * @param method   方法名
	 * @param params   参数
	 * @param clazz    类
	 * @return
	 */
	public static <T> T execMethod(String filePath, String method, Object[] params, Class<T> clazz) {
		// 获得TestGroovy的实例
		GroovyObject groovyObject = getGroovyObject(filePath);
		// 反射调用printArgs方法得到返回值
		return execMethod(groovyObject, method, params, clazz);
	}

	/**
	 * 执行方法
	 * 
	 * @param <T>
	 * @param filePath Groovy文件地址
	 * @param method   方法名
	 * @param clazz    类
	 * @return
	 */
	public static <T> T execMethod(String filePath, String method, Class<T> clazz) {
		// 获得TestGroovy的实例
		GroovyObject groovyObject = getGroovyObject(filePath);
		// 反射调用printArgs方法得到返回值
		return execMethod(groovyObject, method, clazz);
	}

}
